#include<unistd.h>
#include<string.h>
#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/wait.h>
#include<fcntl.h>
using namespace std;


int SetNonBlock(int fd)
{
    int fl = fcntl(fd, F_GETFL, 0);
    if (fl == -1) return -1;
    fl |= O_NONBLOCK;

    int ret = fcntl(fd, F_SETFL, fl);
    if (ret == -1) return -1;
}



int main()
{
    int pipefd[2];   //用来接收管道的fd
    int n = pipe(pipefd);    /*传进去是数组的首地址， 然后根据首地址就能拿到数组， 往里边放上管道的fd。*/
    if (n < 0) return -1;    /*创建管道失败*/    
    
    SetNonBlock(pipefd[0]);  //设置读端非阻塞

    pid_t id = fork();
    if (id == 0) /*子进程, 读端*/
    {

        close(pipefd[1]);  /*关闭写端*/

        char buffer[128];
        
        while (1)
        {
            int n = read(pipefd[0], buffer, sizeof(buffer) - 1);   
            if (n > 0) 
            {
                buffer[n] = 0;
                cout << buffer << endl;
            }
            else if (n == 0)    /*写端关了， 然后读端已经把数据全都都上来了， 此时规定读端已经把数据读到了末尾了EOF，已经把数据读完了*/
            {
                exit(0);
            }
            else   /*文件读取失败，信号中断、非阻塞读取、读端文件描述符异常关闭等等*/
            {   
                cout << "非阻塞， 退出了" << endl;
                exit(0);
            }
        }

        close(pipefd[0]);  /*关闭读端*/
        exit(0);
    }
    else if (id > 0) /*父进程， 写端*/
    {

        close(pipefd[0]); /*关闭读端*/
        
        char* mes = "i am father";
        int n = write(pipefd[1], mes, strlen(mes));
        if (n > 0) /*写入成功*/
        {
        }
        else if (n == 0) /*请求正好写入0个数据*/
        {
        }
        else    /*读端关闭， 继续写入直接-1， 或者非阻塞下管道满了*/
        {
            return -1;
        }

        sleep(5);
        close(pipefd[1]);/*关闭读端*/
    }
    else /*创建进程失败*/
    {
        return -1;
    }

    waitpid(id, nullptr, 0);   /*等待子进程*/

    return 0;
}